<?php
# autoHTML: the dynamic PHP5 library for fast website prototyping
# http://code.google.com/p/autohtml/
#
# Copyright (c) 2010, Shu Zong Chen
# http://freelanceDreams.com/
# All rights reserved. 
# 
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions are met: 
# 
#  * Redistributions of source code must retain the above copyright notice, 
#    this list of conditions and the following disclaimer. 
#  * Redistributions in binary form must reproduce the above copyright 
#    notice, this list of conditions and the following disclaimer in the 
#    documentation and/or other materials provided with the distribution. 
#  * Neither the name of autoHTML nor the names of its contributors 
#    may be used to endorse or promote products derived from this software 
#    without specific prior written permission. 
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.

class AUTOHTML_HEADER{
	public $XHTML_MODE = false;
	public $END_TAG = '>';
	function AUTOHEADER(){
		$this->DOCTYPE = new AUTOHTML_HEADER_DOCTYPE($this);
		$this->HTML_TAG = new AUTOHTML_HEADER_HTML_TAG($this);
		$this->HTTP_EQUIV = new AUTOHTML_HEADER_HTTP_EQUIV($this);
		$this->TITLE = new AUTOHTML_HEADER_TITLE($this);
		$this->CSS = new AUTOHTML_HEADER_CSS($this);
		$this->JS = new AUTOHTML_HEADER_JS($this);
		$this->SHORTCUT_ICON = new AUTOHTML_HEADER_SHORTCUT_ICON($this);
		$this->META_TAG = new AUTOHTML_HEADER_META_TAG($this);
		$this->META = new AUTOHTML_HEADER_META($this);
	}
	function __construct(){
		return $this->AUTOHEADER();
	}
	function render(){
		$this->DOCTYPE->render();
		$this->HTML_TAG->render();
		echo "<head>\n";
		$this->HTTP_EQUIV->render();
		$this->SHORTCUT_ICON->render();
		$this->META_TAG->render();
		$this->TITLE->render();
		$this->CSS->render();
		$this->JS->render();
		$this->META->render();
		echo "</head>\n";
	}

	function setXHTML($bool){
		$this->XHTML = $bool;
		$this->END_TAG = $this->XHTML ? ' />': '>';
	}
	####### METHODS #############
	function attachDocType($string){
		/* Automates attaching html and xhtml doctypes. Because who really remembers
		## any of these?  Also, it's neat to be able to just change one variable to change
		## the entire site doctype.  This will be called by __construct so long as you set
		## a doctype in your config array.
		*/
		switch ($string){
			case 'XHTML':
			case 'XHTML 1':
			case 'XHTML 1.0':
			case 'XHTML 1.0 STRICT':
				$this->DOCTYPE->replace('XHTML 1.0 STRICT');
				$this->setXHTML(true);
				return;
			case 'XHTML 1.0 TRANSITIONAL':
				$this->DOCTYPE->replace('XHTML 1.0 TRANSITIONAL');
				$this->setHTML(true);
				return;
			case 'XHTML 1.0 FRAMESET':
				$this->DOCTYPE->replace('XHTML 1.0 FRAMESET');
				$this->setHTML(true);
				return;
			case 'XHTML 1.1':
			case 'XHTML 1.1 DTD':
				$this->DOCTYPE->replace('XHTML 1.1 DTD');
				$this->setHTML(true);
				return;
			case 'HTML':
			case 'HTML 4.01':
			case 'HTML 4.01 STRICT':
				$this->DOCTYPE->replace('HTML 4.01 STRICT');
				$this->setHTML(false);
				return;
			case 'HTML 4.01 FRAMESET':
				$this->DOCTYPE->replace('HTML 4.01 FRAMESET');
				$this->setHTML(false);
				return;
			default:
			case 'HTML 4.01 TRANSITIONAL':
				$this->DOCTYPE->replace('HTML 4.01 TRANSITIONAL');
				$this->setHTML(false);
				return;
		}
	}
	function setIcon($uri){
		$this->SHORTCUT_ICON->attach(
			array(
				'rel' => 'shortcut icon',
				'href' => $uri,
				'type' => 'image/x-icon'
			)
		);
		$this->SHORTCUT_ICON->attach(
			array(
				'rel' => 'icon',
				'href' => $uri,
				'type' => 'image/x-icon'
			)
		);
	}
	function JS_init($string){
		$this->JS_init->attach($string);
	}
	function attachJS($file){
		if (substr($file, 0, 1) == "/"){
			$fn = $file;
		}else{
			$fn = "{$this->CONFIG["http_js"]}/{$file}";
		}
		$this->JS->attach(array('src'=>$fn));
	}
	function setTitle($string){
		$this->TITLE->attach($string);
	}
	function redirect($target, $time){
		$this->META->attach("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"$time;url=$target\">");
	}
}

abstract class AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 0;
	protected $ELEMENTS = null;
	protected $MULTIPLE_ELEMENTS = true;
	protected $PARENT = null;
	function __construct($parent){
		$this->PARENT = $parent;
	}
	function attach($element){
		if (!$MULTIPLE_ELEMENTS || empty($this->ELEMENTS)){
			$this->ELEMENTS = array();
		}
		$this->ELEMENTS[] = $element;
		return $element;
	}
	function replace($element){
		$this->ELEMENTS = null;
		return $this->attach($element);
	}
	function renderElement($e){
		return $e['value'];
	}
	function render(){
		if (empty($this->ELEMENTS)){
			return false;
		}
		foreach ($this->ELEMENTS as $e){
			echo str_repeat("\t", $this->TAB_INDENT), $this->renderElement($e), "\n";
		}
		return true;
	}
}
class AUTOHTML_HEADER_DOCTYPE extends AUTOHTML_HEADER_GENERIC{
	protected $MULTIPLE_ELEMENTS = false;
	public static $DOCTYPES = array(
		'XHTML 1.0 STRICT' => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">",
		'XHTML 1.0 TRANSITIONAL' => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
		'XHTML 1.0 FRAMESET' => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">",
		'XHTML 1.1 DTD' => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">",
		'HTML 4.01 STRICT' => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n\"http://www.w3.org/TR/html4/strict.dtd\">",
		'HTML 4.01 FRAMESET' => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"\n\"http://www.w3.org/TR/html4/frameset.dtd\">",
		'HTML 4.01 TRANSITIONAL' => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n\"http://www.w3.org/TR/html4/loose.dtd\">"
	);
	function renderElement($e){
		echo self::$DOCTYPES[$e];
	}
}

class AUTOHTML_HEADER_CSS extends AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 1;
	function renderElement($e){
		switch ($e['style']){
			case 'INLINE':
				$css = $this->loadFile($e['uri']);
				return "<style>\n{$css}</style>";
			case 'LINK':
				return "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$e['uri']}\" media=\"{$e['media']}\"" . $this->PARENT->END_TAG;
			default:
			case 'IMPORT':
				return "<style type=\"text/css\">@import url({$e['uri']});</style>";
		}
	}
}

class AUTOHTML_HEADER_SHORTCUT_ICON extends AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 1;
	function renderElement($e){
		return "<link rel=\"{$e['rel']}\" href=\"{$e['uri']}\" type=\"{$e['type']}\"" . $this->PARENT->END_TAG;
	}
}

class AUTOHTML_HEADER_JS extends AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 1;
	function renderElement($e){
		return "<script type=\"text/javascript\" src=\"{$e['src']}\"></script>";
	}
}

class AUTOHTML_HEADER_META extends AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 1;
	function renderElement($e){
		return $e;
	}
}

class AUTOHTML_HEADER_TITLE extends AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 1;
	private $SEPERATOR = " | ";
	function render(){
		if (!empty($this->ELEMENTS)){
			echo str_repeat("\t", $this->TAB_INDENT), '<title>', implode($this->SEPERATOR, $this->ELEMENTS), '</title>', "\n";
		}else{
			echo str_repeat("\t", $this->TAB_INDENT), '<title>No title</title>', "\n";
		}
	}
}

class AUTOHTML_HEADER_META_TAG extends AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 1;
	function renderElement($e){
		return $e;
	}
}

class AUTOHTML_HEADER_HTML_TAG extends AUTOHTML_HEADER_GENERIC{
	function renderElement($e){
		if (isset($this->ELEMENTS[0]) && $this->ELEMENTS[0]=='XHTML'){
			return '<html xmlns="http://www.w3.org/1999/xhtml">';
		}
		return '<html>';
	}
}

class AUTOHTML_HEADER_HTTP_EQUIV extends AUTOHTML_HEADER_GENERIC{
	protected $TAB_INDENT = 1;
	function renderElement($e){
		return "<meta http-equiv=\"{$e['http-equiv']}\" content=\"{$e['content']}; charset={$e['charset']}\"". $this->PARENT->END_TAG;
	}
}